package question2;


import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 有一批任务需要处理，单个任务耗时事件不确定，且每个任务处理完后都会返回生成一个随机数，请最短时间内处理完这批任务，请记录所有任务的返回值，并求和。
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        planB();
    }

    public static ConcurrentLinkedQueue<Task> generateTaskQueue(int taskCount) {
        ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();
        IntStream.range(0, taskCount)
                .mapToObj(
                        i1 -> {
                            int i2 = new Random().nextInt(10);
                            return new Task(i1, i2);
                        }
                )
                .forEach(taskQueue::add);
        return taskQueue;
    }

    public static void planA() throws InterruptedException {
        ConcurrentLinkedQueue<Task> taskQueue = generateTaskQueue(10);
//        Thread t1 = new Thread(new Worker(1, taskQueue));

    }

    public static void planB() throws InterruptedException {
        ConcurrentLinkedQueue<Task> taskQueue = generateTaskQueue(10);

        ExecutorService pool = new ThreadPoolExecutor(
                0
                , 3
                , 0L
                , TimeUnit.MILLISECONDS
                , new LinkedBlockingQueue<Runnable>(1)
                , Executors.defaultThreadFactory()
                , new ThreadPoolExecutor.AbortPolicy()
        );

        Future<ConcurrentHashMap<Integer, Integer>> future1 = pool.submit(new Worker(1, taskQueue));
        Future<ConcurrentHashMap<Integer, Integer>> future2 = pool.submit(new Worker(2, taskQueue));
        Future<ConcurrentHashMap<Integer, Integer>> future3 = pool.submit(new Worker(3, taskQueue));

        try {
            ConcurrentHashMap<Integer, Integer> res1 = future1.get();
            ConcurrentHashMap<Integer, Integer> res2 = future2.get();
            ConcurrentHashMap<Integer, Integer> res3 = future3.get();
            int sum1 = res1.values().stream().mapToInt(integer -> integer).sum();
            int sum2 = res2.values().stream().mapToInt(integer -> integer).sum();
            int sum3 = res3.values().stream().mapToInt(integer -> integer).sum();
            int res = sum1 + sum2 + sum3;
            System.out.println(res);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        pool.shutdown();
    }

    public static void planC() throws InterruptedException {
        ConcurrentLinkedQueue<Task> taskQueue = generateTaskQueue(10);

        ExecutorService pool = new ThreadPoolExecutor(
                0
                , 3
                , 0L
                , TimeUnit.MILLISECONDS
                , new LinkedBlockingQueue<Runnable>(1)
                , Executors.defaultThreadFactory()
                , new ThreadPoolExecutor.AbortPolicy()
        );

        List<Worker> workerList = Stream.of(new Worker(1, taskQueue), new Worker(2, taskQueue), new Worker(3, taskQueue))
                .collect(Collectors.toList());
        List<Future<ConcurrentHashMap<Integer, Integer>>> futureList = pool.invokeAll(workerList);

        int res = futureList.stream()
                .map(
                        f -> {
                            try {
                                return f.get().values();
                            } catch (InterruptedException | ExecutionException e) {
                                throw new RuntimeException(e);
                            }
                        }
                )
                .flatMap(Collection::stream)
                .reduce(0, Integer::sum);
        System.out.println(res);
        pool.shutdown();
    }
}
